classdef LowPassFilter < EquipmentControl.FeedBackOptimization.LTIUnit.AbstractLTIUnit
    %LOWPASSFILTER Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        order
        bandwidth
        timeconst
    end
    
    methods
        function obj = LowPassFilter(order, bw, varargin)
            %LOWPASSFILTER Construct an instance of this class
            %   Detailed explanation goes here
            p=inputParser;
            orderCheck = @(x) ismember(x, 1:8);
            isPositive = @(x) x > 0.0;
            p.addRequired('order', orderCheck);
            p.addRequired('bw', isPositive);
            p.addParameter('gain', 1.0, @isnumeric);
            p.addParameter('name', sprintf('LP%d',order), @ischar);
            p.parse(order, bw, varargin{:});
            
            tc = ziBW2TC(bw, order);
            num = p.Results.gain; den = arrayfun(@(k) nchoosek(order, k)*(tc.^k), order:-1:0);
            obj@EquipmentControl.FeedBackOptimization.LTIUnit.AbstractLTIUnit(p.Results.name, num, den);

            obj.gain = p.Results.gain;
            obj.order = order;
            obj.bandwidth = bw;
            obj.timeconst = tc;
        end
        
        function [tf1, tau1, tDelay] = firstOrderApprox(obj, varargin)
            p=inputParser;
            methodCheck = @(x) ismember(x, 'approximate', 'numerical');
            p.addParameter('method', 'approximate', methodCheck);
            p.parse(varargin{:});
            
            if obj.order == 1
                tf1 = obj.tfFunction;
                tau1 = obj.timeconst;
                tDelay = 0;
            else
                switch p.Results.method
                    case{'approximate'}
                        % use approximate results
                        tDelay = (-1.3+0.7*obj.order)*obj.timeconst;
                        tau1 = obj.order*obj.timeconst - tDelay;
                    case{'numerical'}
                        % use numerical results
                        [~, tau1, tDelay] = firstOrderApprox@EquipmentControl.FeedBackOptimization.LTIUnit.AbstractLTIUnit(obj);
                end
                s=tf('s');
                tf1 = obj.gain/(1+tau1*s) * exp(-tDelay*s);
            end
        end
        
    end
end

